
import json
import numpy as np
import matplotlib.pyplot as plt
import os
import imageio.v2 as imageio

def readData(file_name):
    """从JSON文件中提取所有的节点列表

    Args:
        file_name (str): JSON文件名
    """

    data = []
    with open(file_name,'r') as file:
        data = json.load(file)

    if data == []:
        print("Data read error")
        pass

    sat_name_list = []
    base_name_list = []
    uav_name_list = []
    DATA_DIC = {}
    for data_item in data:
        node_1_name = data_item['node1']
        node_1_type = node_1_name[0]
        if node_1_type == "S":
            sat_name_list.append(node_1_name)
        elif node_1_type == "G":
            base_name_list.append(node_1_name)
        elif node_1_type == "U":
            uav_name_list.append(node_1_name)

        node_2_name = data_item['node2']
        if node_2_name == None:
            continue
        node_2_type = node_2_name[0]
        if node_2_type == "S":
            sat_name_list.append(node_2_name)
        elif node_2_type == "G":
            base_name_list.append(node_2_name)
        elif node_2_type == "U":
            uav_name_list.append(node_2_name)

        DATA_DIC[node_1_name,node_2_name] = data_item['distance']

    import re
    # 获取各类型节点的名称列表及其个数
    sat_name_list = sorted(list(set(sat_name_list)))
    plane_index,sat_index = [],[]
    for sat_item in sat_name_list:
        numbers = list(map(int, re.findall(r'\d+', sat_item)))
        now_plane_num = numbers[0]
        now_sat_num = numbers[1]
        plane_index.append(now_plane_num)
        sat_index.append(now_sat_num)
    numOrbitPlanes = max(plane_index)+1
    numSatsPerPlane = max(sat_index)+1
    sat_name_list = []
    for i in range(numOrbitPlanes):
        for j in range(numSatsPerPlane):
            sat_name_list.append(f'SP{i}S{j}')
    sat_name_list = sorted(list(set(sat_name_list)))
    sat_num = numOrbitPlanes*numSatsPerPlane

    base_name_list = sorted(list(set(base_name_list)))
    base_num = len(base_name_list)

    uav_name_list = sorted(list(set(uav_name_list)))
    uav_num = len(uav_name_list)

    # 构造节点名称-序号的字典映射并构建邻接矩阵
    all_node_list = sat_name_list + base_name_list + uav_name_list
    NODE_INDEX_DIC = {}
    for index, node_name in enumerate(all_node_list):
        NODE_INDEX_DIC[node_name] = index

    adjacency_mat = np.zeros((len(all_node_list),len(all_node_list)))
    for node_1_name in all_node_list:
        for node_2_name in all_node_list:
            perf_Range = DATA_DIC.get((node_1_name,node_2_name),None)
            if perf_Range != None:
                adjacency_mat[NODE_INDEX_DIC[node_1_name],NODE_INDEX_DIC[node_2_name]] = 1
                adjacency_mat[NODE_INDEX_DIC[node_2_name],NODE_INDEX_DIC[node_1_name]] = 1

    return adjacency_mat
    

if __name__ == "__main__":

    data_directory = os.path.join(os.getcwd(),'data')
    if not os.path.exists('figs'): os.makedirs('figs')
    figs_directory = os.path.join(os.getcwd(),'figs')
    files = os.listdir(data_directory)
    file_name_list = [file_name for file_name in files if file_name[-5:]=='.json' ]

    def draw_access_data(file_name):
        adjacency_mat = readData(os.path.join(data_directory,file_name))
        plt.imshow(adjacency_mat, cmap='gray', interpolation='nearest')
        plt.savefig(os.path.join(figs_directory,file_name[0:-5]+'.png'))
       
    from joblib import Parallel, delayed
    Parallel(n_jobs=-1)(
        delayed(draw_access_data)(file_name) 
        for file_name in file_name_list
    )
    
    output_gif = "TOPO.gif"
    
    image_files = sorted(
        [os.path.join(figs_directory, f) for f in os.listdir(figs_directory) if f.endswith(".png")],
        key=lambda x: x.lower()
    )# 确保按序号排序
    
    # region 拼接帧为GIF
    print("INFO: 拼接帧为GIF...")

    frames = []
    for path in image_files:  
        frames.append(imageio.imread(path))

    # 保存为GIF
    imageio.mimsave(output_gif, frames, fps=10, loop=0)
    print("INFO: GIF生成完成！")

    # 删除临时帧文件
    import shutil
    shutil.rmtree("figs")

    # endregion

    print(f"GIF 文件已生成：{output_gif}")
